/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hhf.flex;

import flex.messaging.FlexContext;
import flex.messaging.FlexFactory;
import flex.messaging.MessageException;
import flex.messaging.messages.Message;
import flex.messaging.messages.RemotingMessage;
import flex.messaging.services.ServiceAdapter;
import flex.messaging.services.remoting.RemotingDestination;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.lang.reflect.Method;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 *
 * @author fach
 */
public class EJBAdapter extends ServiceAdapter {

	private InitialContext ic;
	private String prefixJndi;

	public EJBAdapter() {
		super();
		try {
			ic = new InitialContext();
			String appname = (String) ic.lookup("java:app/AppName");
			String mname = (String) ic.lookup("java:module/ModuleName");
			prefixJndi = "java:global/" + appname + "/";
		} catch (NamingException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 
	 * @param message
	 * @return 
	 */
	@Override
	public Object invoke(Message message) {
		RemotingMessage remotingMessage = (RemotingMessage) message;
		List<Object> parameters = remotingMessage.getParameters();
		String methodName = remotingMessage.getOperation();
		RemotingDestination remotingDestination = (RemotingDestination) getDestination();
		String source = remotingDestination.getSource();
		String scope = remotingDestination.getScope();
		String jndi = prefixJndi + source;
		try {
			Object ejb = null;
			if (FlexFactory.SCOPE_SESSION.equals(scope)) {
				ejb = FlexContext.getFlexSession().getAttribute(source);
				if (ejb == null) {
					ejb = ic.lookup(jndi);
				}
				FlexContext.getFlexSession().setAttribute(source, ejb);
			} else {
				ejb = ic.lookup(jndi);
			}
			Class<?>[] parameterTypes = new Class<?>[parameters.size()];
			Object[] params = new Object[parameters.size()];
			int i = 0;
			for (Object obj : parameters) {
				params[i] = obj;
				parameterTypes[i++] = obj.getClass();
			}
			Method method = ejb.getClass().getMethod(methodName, parameterTypes);
			return method.invoke(ejb, params);
		} catch (InvocationTargetException cause) {
			Throwable throwable = cause.getCause();
			MessageException me = new MessageException(throwable.getMessage());
			me.setCode(throwable.getClass().getName());
			StackTraceElement[] stes = throwable.getStackTrace();
			StringBuilder stringBuilder = new StringBuilder();
			String indent = "";
			for (StackTraceElement ste : stes) {
				stringBuilder.append(indent).append(ste.getClassName()).append(".").append(ste.getMethodName()).append("[").append(ste.getLineNumber()).append("]\n");
				indent += " ";

			}
			me.setDetails(stringBuilder.toString());
			throw me;
		} catch (Exception cause) {
			cause.printStackTrace();
			MessageException me = new MessageException(cause.getClass().getName() + " : " + cause.getMessage());
			me.setCode("Server.Processing");
			me.setRootCause(cause);
			throw me;
		}
	}
}
